package com.cube.truthseer.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cube.truthseer.common.cache.Cache;
import com.cube.truthseer.common.entity.constants.MqConstants;
import com.cube.truthseer.common.entity.constants.RedisConstants;
import com.cube.truthseer.common.entity.vo.ResultMessage;
import com.cube.truthseer.common.exception.BadRequestException;
import com.cube.truthseer.common.exception.ForbiddenException;
import com.cube.truthseer.common.minio.MinIOUtil;
import com.cube.truthseer.common.mq.RabbitMqHelper;
import com.cube.truthseer.common.security.AuthUser;
import com.cube.truthseer.common.security.context.UserContext;
import com.cube.truthseer.common.security.token.TokenUtil;
import com.cube.truthseer.common.security.token.base.AbstractTokenGenerate;
import com.cube.truthseer.common.utils.ResultUtil;
import com.cube.truthseer.common.utils.StringUtil;
import com.cube.truthseer.common.utils.UserRequest;
import com.cube.truthseer.entity.bucket.po.Bucket;
import com.cube.truthseer.mapper.BucketMapper;
import com.cube.truthseer.service.IBucketService;
import io.minio.errors.MinioException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

import static com.cube.truthseer.common.entity.constants.RedisConstants.BUCKET_USER_DETAIL;
import static com.cube.truthseer.common.entity.constants.RedisConstants.BUCKET_USER_DETAIL_TTL;
import static com.cube.truthseer.entity.user.constants.UserErrorInfo.Msg.ILLEGAL_LOGIN_TYPE;
import static com.cube.truthseer.entity.user.constants.UserErrorInfo.Msg.USER_ID_NOT_EXPIRE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zw
 * @since 2024-03-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BucketServiceImpl extends ServiceImpl<BucketMapper, Bucket> implements IBucketService {
    private final MinIOUtil minIOUtil;
    private final StringRedisTemplate stringRedisTemplate;
    private final Cache<Bucket> bucketCache;
    private final RabbitMqHelper mqHelper;
    private final TokenUtil tokenUtil;

    @Override
    @Transactional
    public ResultMessage<Object> queryBucketDetail() {
        //1,获取线程中的用户

        String token = UserRequest.getCurrentToken();
        log.info("token:"+token);
        AuthUser authUser = tokenUtil.parseToken(token);
        String userId =String.valueOf( authUser.getId());
        if(userId==null||StringUtil.isBlank(userId)){
            throw new BadRequestException(USER_ID_NOT_EXPIRE);
        }
        //获取minio对象，统计桶的大小,我同意有适当不对的数据，我这是redis查本地缓存
        Bucket redisBucket = bucketCache.get(BUCKET_USER_DETAIL + userId);
        if(redisBucket==null){
            //如果没有，就查询数据库
            redisBucket = lambdaQuery().eq(Bucket::getBucketName, userId).one();
        }
        //异步更新
        mqHelper.send(MqConstants.Exchange.BUCKET_EXCHANGE,MqConstants.Key.BUCKET_CAPACITY,userId);

        return ResultUtil.data(redisBucket);

    }

    //计算桶的容量
    @Override
    @Transactional
    public void calBucketCapacity(String bucketName) {
        log.info("bucketName:"+bucketName);
        try {
            //获取桶的容量
            String bucketUsage = minIOUtil.getBucketUsageWithUnit(bucketName);
            log.info("bucketUsage:"+bucketUsage);
            //获取数据库的桶信息
            Bucket bucket = lambdaQuery().eq(Bucket::getBucketName, bucketName).one();
            bucket.setUserdSize(bucketUsage);
            //更新
            bucket.setUserdSize(bucketUsage);
//            bucket.setTotalSize(bucketName);
            //保存数据库
            updateById(bucket);
            //再修改
            bucketCache.put(BUCKET_USER_DETAIL,bucket,30L, TimeUnit.MINUTES);
        } catch (MinioException e) {
            e.printStackTrace();
        }
    }

}
